<!DOCTYPE html>
<html lang="zh-cn">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>激活码生成器</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            margin: 20px;
        }
        .container {
            max-width: 400px;
            margin: auto;
        }
        .input-group {
            margin-bottom: 15px;
        }
        .input-group label {
            display: block;
            margin-bottom: 5px;
        }
        .input-group input, .input-group textarea {
            width: 100%;
            padding: 8px;
            box-sizing: border-box;
        }
        .button-group {
            display: flex;
            justify-content: space-between;
        }
        .button-group button {
            padding: 10px 20px;
            cursor: pointer;
        }
    </style>
</head>
<body>
    <div class="container">
        <div class="input-group">
            <label for="ciphertext">密文</label>
            <input type="text" id="ciphertext">
        </div>
        <div class="input-group">
            <label for="activation-code">激活码</label>
            <textarea id="activation-code" rows="3" readonly></textarea>
        </div>
        <div class="button-group">
            <button onclick="generateActivationCode()">生成激活码</button>
            <button onclick="copyActivationCode()">一键复制激活码</button>
        </div>
    </div>

    <script>
        const SMS_SIZE = 7 * 4;
        const PLAINTEXT_SIZE = SMS_SIZE // 4;
        const CIPHERTEXT_SIZE = SMS_SIZE;

        class RSA {
            encrypt(plainText, publicKey) {
                const [n, e] = publicKey;
                const cipherText = new Uint8Array(CIPHERTEXT_SIZE);
                for (let i = 0; i < PLAINTEXT_SIZE; i++) {
                    let m = 1;
                    for (let j = 0; j < e; j++) {
                        m = (m * plainText[i]) % n;
                    }
                    const ctr = i * 4;
                    cipherText[ctr] = m & 0xFF;
                    cipherText[ctr + 1] = (m >> 8) & 0xFF;
                    cipherText[ctr + 2] = (m >> 16) & 0xFF;
                    cipherText[ctr + 3] = (m >> 24) & 0xFF;
                }
                return cipherText;
            }

            getFirstTwoNonZeroHighLowNibbles(cipherText) {
                const nonZeroBytes = Array.from(cipherText).filter(byte => byte !== 0);
                if (nonZeroBytes.length < 2) {
                    throw new Error("加密后的消息中没有足够的非零字节");
                }
                const firstByte = nonZeroBytes[0];
                const secondByte = nonZeroBytes[1];
                const highNibbleFirstByte = (firstByte >> 4) & 0x0F;
                const lowNibbleFirstByte = firstByte & 0x0F;
                const highNibbleSecondByte = (secondByte >> 4) & 0x0F;
                const lowNibbleSecondByte = secondByte & 0x0F;
                return [highNibbleFirstByte, lowNibbleFirstByte, highNibbleSecondByte, lowNibbleSecondByte];
            }
        }

        function generateActivationCode() {
            let plainText = document.getElementById('ciphertext').value;
            if (plainText.length < 6) {
                alert('明文格式错误，长度不足六位');
                return;
            }
            if (plainText.length > PLAINTEXT_SIZE) {
                plainText = plainText.slice(-PLAINTEXT_SIZE + 1);
                alert(`输入过长，取后六位：${plainText}`);
            }
            const plainTextBytes = new TextEncoder().encode(plainText + "\0");

            const rsaInstance = new RSA();
            const publicKey = [24287, 11]; // 示例公钥
            const cipherText = rsaInstance.encrypt(plainTextBytes, publicKey);

            const [A, B, C, D] = rsaInstance.getFirstTwoNonZeroHighLowNibbles(cipherText);
            const out = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F"];
            const activationCode = `${out[A]}${out[B]}${out[C]}${out[D]}`;

            document.getElementById('activation-code').value = activationCode;
        }

        function copyActivationCode() {
            const activationCode = document.getElementById('activation-code');
            activationCode.select();
            document.execCommand('copy');
            alert('激活码已复制到剪贴板');
        }
    </script>
</body>
</html>